using System;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.IO;
using System.Xml;
using System.Diagnostics;
using System.Security;
using System.Resources;
using System.Reflection;
using System.Windows.Forms;
using System.Configuration;

using Microsoft.ApplicationBlocks.ExceptionManagement;


namespace ExceptionHandler
{
	public class ExceptionPublisher : IExceptionPublisher
	{
		
		private XmlDocument oCustomMessageXML		=	new XmlDocument();
		private string sErrMessage					=	string.Empty;
		private string sExceptionMessage			=	string.Empty;
		private string bLogError					=	"true";
		private string bShowMessage					=	"true";
		private string sMessageType					=	"None";

		private string sApplicationName = "PressPass";
		private const string TEXT_SEPARATOR = "*********************************************";

		private static ResourceManager resourceManager = new ResourceManager(typeof(ExceptionPublisher).Namespace + ".ExceptionManagerText",Assembly.GetAssembly(typeof(ExceptionPublisher)));

		// Xml Custom Message Loading
		public void Load_Xml()
		{
			oCustomMessageXML.Load(AppDomain.CurrentDomain.BaseDirectory  + "\\..\\..\\CustomMessage.xml");
		}

		public ExceptionPublisher()
		{
			try
			{
				sApplicationName=ConfigurationSettings.AppSettings["ApplicationName"].ToString();
			}
			catch{}
		}
		// Provide implementation of the IPublishException interface
		// This contains the single Publish method.
		void IExceptionPublisher.Publish(Exception exception, NameValueCollection AdditionalInfo, NameValueCollection ConfigSettings)
		{
			Load_Xml();
			sExceptionMessage = exception.Message;
					
			XmlNode oNode = oCustomMessageXML.SelectSingleNode("//CustomMessages/CustomMessage[MessageKey/text()='" + sExceptionMessage + "']");
			if (oNode!=null)
			{
				for(int i=0;i<oNode.ChildNodes.Count;i++)
				{
					switch(oNode.ChildNodes[i].Name)
					{
						case "Message":
							sErrMessage = oNode.ChildNodes[i].InnerText; 
							break;
						case "LogMessage":
							bLogError = oNode.ChildNodes[i].InnerText; 
							break;
						case "ShowMessage":
							bShowMessage = oNode.ChildNodes[i].InnerText; 
							break;
						case "MessageType":
							sMessageType = oNode.ChildNodes[i].InnerText;
							break;

					}
				}
			}
			else
			{
				//Custom Default Message
				sErrMessage=sExceptionMessage;
			}

			string sShowMessage=string.Empty;
			if (exception.InnerException!=null)
			{
				sShowMessage = sErrMessage + " : " + exception.InnerException.Message;
			}
			else
				sShowMessage=sErrMessage;
	
			if ((bShowMessage == "true") && (sErrMessage!="") && (sErrMessage!=String.Empty) )
			{
				switch(sMessageType)				
				{
					case "Error":
						MessageBox.Show(sShowMessage,sApplicationName,MessageBoxButtons.OK,MessageBoxIcon.Error);
						break;
					case "Warning":
						MessageBox.Show(sShowMessage,sApplicationName,MessageBoxButtons.OK,MessageBoxIcon.Warning);
						break;
					case "Information":
						MessageBox.Show(sShowMessage,sApplicationName,MessageBoxButtons.OK,MessageBoxIcon.Information);
						break;
					default:
						MessageBox.Show(sShowMessage,sApplicationName,MessageBoxButtons.OK,MessageBoxIcon.None);
						break;

				}
			}

			if(bLogError=="true")
			{
				if (exception.InnerException!=null)
				{
					//This is to check where it is having Custom message
					if(oNode!=null)
						LogError(new Exception(sErrMessage + "\n" + exception.InnerException.Message),AdditionalInfo,ConfigSettings);
					else
						LogError(exception.InnerException,AdditionalInfo,ConfigSettings);
				}
				else
				{
					LogError(new Exception(sErrMessage),AdditionalInfo,ConfigSettings);
				}
			}
		}

		private void LogError(Exception exception, NameValueCollection additionalInfo, NameValueCollection ConfigSettings)
		{
			// Create StringBuilder to maintain publishing information.
			StringBuilder strInfo = new StringBuilder();

			#region Record the contents of the AdditionalInfo collection
			// Record the contents of the AdditionalInfo collection.
			if (additionalInfo != null)
			{
				// Record General information.
				strInfo.AppendFormat("{0}General Information {0}{1}{0}Additional Info:", Environment.NewLine, TEXT_SEPARATOR);

				foreach (string i in additionalInfo)
				{
					strInfo.AppendFormat("{0}{1}: {2}", Environment.NewLine, i, additionalInfo.Get(i));
				}
			}
			#endregion

			if (exception == null)
			{
				strInfo.AppendFormat("{0}{0}No Exception object has been provided.{0}", Environment.NewLine);
			}
			else
			{
				strInfo.AppendFormat("{0}{0}Exception Information{0}{1}", Environment.NewLine, TEXT_SEPARATOR);
				strInfo.AppendFormat("{0}{1}", Environment.NewLine, "Exception Type: User Defined Exceptions");
				strInfo.AppendFormat("{0}{1}", Environment.NewLine, exception.Message);
			}

			// Write the entry to the event log.   
			WriteToLog(strInfo.ToString(), EventLogEntryType.Error);
		}

		private void WriteToLog(string entry, EventLogEntryType type)
		{
			try
			{
				// Write the entry to the Event Log.
				EventLog.WriteEntry(sApplicationName,entry,type);
			}
			catch(SecurityException e)
			{				
				throw new SecurityException(String.Format(resourceManager.GetString("RES_DEFAULTPUBLISHER_EVENTLOG_DENIED"), sApplicationName),e);
			}
		}


	}
}
